package dd.view;

import java.awt.Canvas;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import dd.model.Edge;
import dd.model.Event;
import dd.model.Model;

public class DrawingCanvas extends Canvas {
	private Event event;
	private int arr[] = new int[10];
	private int choiceCount;
	private int horizationalPos;
	private ArrayList<Edge> ledge;
	private Map<Integer, String> choicesMap;
	private Map<Integer, String> resultsMap;

	private DrawingCanvas() {
		// force the Event?
	}

	public DrawingCanvas(Event e) {
		this.event = e;
	}

	public void paint(Graphics g) {
		Model m = Model.getInstance();
		event = m.getEvent();
		this.choicesMap = new HashMap<Integer, String>();
		this.resultsMap = new HashMap<Integer, String>();
		Model model = Model.getInstance();
		event = model.getEvent();
		choiceCount = event.getNumberLines();
		ledge = event.getedgelist();
		int panelWidth = getWidth();
		int lineGap = (panelWidth - 40) / choiceCount;
		System.out.println("The lineGap is " + lineGap);
		int linePosX = getX() - 75;
		int lineLength = 150;
		horizationalPos = getY();
		System.out.println("Number of choices in drawing canvas: " + event.getNumberLines() + "");
		for (int i = 0; i < choiceCount; i++) {

			linePosX = linePosX + lineGap;
			g.drawRect(linePosX - 25, horizationalPos - 30, 120, 20);
			g.drawString(event.getChoice(i), linePosX - 20, horizationalPos - 15);
			g.drawLine(linePosX, horizationalPos, linePosX, horizationalPos + lineLength);
			this.choicesMap.put(2 * i, event.getChoice(i));
			this.resultsMap.put(2 * i, "Result" + (i + 1));
			arr[i] = linePosX;
		}
		for (int j = 0; j < ledge.size(); j++) {
			drawEdge(ledge.get(j));
		}
	}

	public void update(Graphics g) {
		Model model = Model.getInstance();
		event = model.getEvent();
		choiceCount = this.event.getNumberLines();
		ledge = event.getedgelist();
		for (int j = 0; j < ledge.size(); j++) {
			drawEdge(ledge.get(j));
		}
	}

	public int getarr(int i) {
		return arr[i];
	}

	public int getarrsize() {
		return choiceCount;
	}

	public void drawedge(int l, int r, int h) {
		Graphics g = this.getGraphics();
		g.drawLine(l, h, r, h);
	}

	public void drawEdge(Edge edge) {
		int l, leftchoice;
		int r, rightchoice;
		int h, height;
		leftchoice = edge.getleft();
		rightchoice = edge.getright();
		height = edge.getheight();
		Graphics g = this.getGraphics();
		l = arr[leftchoice];
		r = arr[rightchoice];
		h = height + horizationalPos;
		g.drawLine(l, h, r, h);
	}

	public int getlinetop() {
		return horizationalPos;
	}

	public String calcResult(ArrayList<Edge> edgelist) {

		String resultstring = "";
		int[][] matrix = new int[edgelist.size()][event.getNumberLines() * 2 - 1];
		Map<Integer, Integer> result = new HashMap<Integer, Integer>();

		Collections.sort(edgelist, new EdgeComparator());
		for (int i = 0, size = edgelist.size(); i < size; i++) {
			Edge e = edgelist.get(i);
			int position = e.getright();
			matrix[i][2 * position - 1] = 1;
		}

		for (int i = 0; i < event.getNumberLines() * 2; i += 2) {
			int j = i;
			for (int k = 0; k < edgelist.size(); k++) {
				if (j < event.getNumberLines() * 2 - 2) {
					// check the right side
					int rightCur = matrix[k][j + 1];
					if (rightCur == 1) {
						j += 2;
						continue;
					}
				}
				if (j > 0) {
					// check the left side
					int leftCur = matrix[k][j - 1];
					if (leftCur == 1) {
						j -= 2;
						continue;
					}
				}
			}
			result.put(j, i);
		}

		// System.out.println("Final result = ");
		// for (Integer key : result.keySet()) {
		// System.out.println(resultsMap.get(key) + " : " + choicesMap.get(result.get(key)));
		// resultstring = resultstring + choicesMap.get(result.get(key)) + "   ";
		// }
		Event myEvent = Model.getInstance().getEvent();
		String myChoice = myEvent.getChoice(myEvent.getPostion());
		// =.=
		for (Integer key : result.keySet()) {
			if (choicesMap.get(result.get(key)).equals(myChoice)) {
				myEvent.setMyResult(resultsMap.get(key));
				break;
			}
		}

		return resultstring;

	}

	// for sorting the edge by height, from small to large
	class EdgeComparator implements Comparator<Edge> {
		@Override
		public int compare(Edge o1, Edge o2) {
			if (o1.getheight() < o2.getheight()) {
				return -1;
			}
			if (o1.getheight() > o2.getheight()) {
				return 1;
			}
			return 0;
		}
	}
}
